/**
 * HTTP 请求工具
 * @description 基于 luch-request 封装的 HTTP 请求工具，提供统一的请求配置、拦截器和错误处理
 * @module utils/request
 * @see https://www.quanzhan.co/luch-request/guide/3.x/
 * @example
 * // 基础用法
 * import { get, post } from '@/utils/request'
 *
 * // GET 请求
 * const data = await get('/api/users')
 *
 * // POST 请求
 * const result = await post('/api/users', { name: 'test' })
 *
 * @example
 * // 自定义配置
 * get('/api/users', null, {
 *   custom: {
 *     loading: true,      // 显示加载提示
 *     auth: false,        // 不需要认证
 *   }
 * })
 */

import Request from 'luch-request'
import {
  API_BASE_URL,
  AUTH_TOKEN_KEY,
  REQUEST_LOADING,
  REQUEST_LOADING_MASK,
  REQUEST_LOADING_TEXT,
  REQUEST_NETWORK_ERROR_TEXT,
  REQUEST_TIMEOUT,
} from '@/config'
import { ResponseCode } from '@/enum'
import store from '@/store'

/**
 * custom 配置项说明：
 * - auth: 是否需要认证，默认为 true
 * - loading: 是否显示加载提示，默认为 REQUEST_LOADING，在 src/config/request.js 中配置
 * - returnResponseHeader: 是否返回响应头，默认为 false
 */

// 创建请求实例
const http = new Request({
  baseURL: API_BASE_URL,
  timeout: REQUEST_TIMEOUT,
  header: {
    'Content-Type': 'application/json',
    'source-client': 'miniapp',
  },
  custom: {
    loading: REQUEST_LOADING,
  },
})

// 请求拦截器
http.interceptors.request.use(
  /**
   * 请求拦截器
   * @param {Object} config 请求配置
   * @returns {Object} 处理后的请求配置
   */
  config => {
    const { custom = {}, header = {} } = config
    const { auth = true, loading } = custom

    // 处理认证
    const token = store.getters.token
    if (token && auth) header[AUTH_TOKEN_KEY] = `Bearer ${token}`
    config.header = header

    // 处理 loading
    loading && uni.showLoading({ title: REQUEST_LOADING_TEXT, mask: REQUEST_LOADING_MASK })
    return config
  },
  error => Promise.reject(error),
)

// 响应拦截器
http.interceptors.response.use(
  response => {
    const { statusCode, data, config } = response
    const { custom = {} } = config
    const { loading } = custom

    // 处理 loading
    loading && uni.hideLoading()

    // 处理成功响应
    if (statusCode >= ResponseCode.SUCCESS && statusCode < 300) return response

    // 处理未授权
    if (statusCode === ResponseCode.UNAUTHORIZED) {
      store.commit('user/CLEAR_USER_INFO')
      store.commit('token/CLEAR_TOKEN')
      uni.navigateTo({ url: '/pages/login/login' })
      return Promise.reject(response)
    }

    // 处理其他错误
    uni.showToast({
      icon: 'none',
      title: data.msg || '请求错误',
    })
    return Promise.reject(response)
  },
  error => {
    const { config } = error
    const { custom = {} } = config || {}
    const { loading } = custom

    // 处理 loading
    loading && uni.hideLoading()

    // 显示错误提示
    uni.showToast({
      icon: 'none',
      title: REQUEST_NETWORK_ERROR_TEXT,
    })
    return Promise.reject(error)
  },
)

/**
 * 基础请求方法
 */
export const request = async config => (await http.request(config)).data

// 导出常用的请求方法
export const get = (url, config) => request({ ...config, url, method: 'GET' })

export const post = (url, data, config) => request({ ...config, url, method: 'POST', data })

export const put = (url, data, config) => request({ ...config, url, method: 'PUT', data })

export const del = (url, config) => request({ ...config, url, method: 'DELETE' })

export default http
